package com.spi.soconversion.util;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;

import com.spi.soconversion.base.definition.COFIOrderLine;
import com.spi.soconversion.base.definition.HeaderCharge;
import com.spi.soconversion.base.definition.LineCharge;
import com.spi.soconversion.base.definition.LineTax;
import com.spi.soconversion.base.definition.OpenSalesOrderDefinition;
import com.spi.soconversion.base.definition.OrderLine;
import com.spi.soconversion.orders.conversion.InvalidItemTypes;

public class MCFConverter {
	
	
    static private org.apache.commons.logging.Log log = 
        org.apache.commons.logging.LogFactory.getLog(MCFConverter.class);

	/**
	 * Determines whether a COFI line is eligible for conversion. If its not, consider it as invalid line.
	 * 
	 * @param itemType
	 * @return
	 */
	public static boolean isInvalidLine(String itemType) {
		boolean result = false;
		if(InvalidItemTypes.getItemType(itemType)!=null) {
			result = true;
		}
		return result;
	}
	
	/**
	 * Determines whether a COFI line is HST eligible or not.
	 * @param line
	 * @return
	 */	
    public static boolean isHSTEligible(COFIOrderLine line) {
    	boolean result = false;
    	String scheduleShipDate = SOCUtility.getDate(SOCUtility.formatDate(line.getScheduleShipDate()));
		String taxProvince = line.getTaxProvince();
		String cashReceiptDate = SOCUtility.formatDate(line.getReceiptDate());
    	
		if(taxProvince!=null && ("BC".equals(taxProvince) ||"ON".equals(taxProvince) )) {
			if(cashReceiptDate!=null && !SOCConstants.EMPTY_STRING.equals(cashReceiptDate) && SOCUtility.compareDates(cashReceiptDate,false)) {
				if(scheduleShipDate!=null && !SOCConstants.EMPTY_STRING.equals(scheduleShipDate) && SOCUtility.compareDates(scheduleShipDate,true)) {
					result=true;
				}
			}
		}
    	
    	return result;
    }

    /**
     * Determines the MCF line status based on COFI line status.
     * 
     * @param line
     * @return
     */
    public static String getMCFLineStatus(COFIOrderLine line) {
    	String cofiLineStatus = line.getLineStatus();
    	String releasedStatus = line.getReleaseStatus();
    	String result = "RELEASED";

    	if ("CLOSED".equals(cofiLineStatus)) {
    		result = "CLOSED";
    	} else if (line.getLineAttribute7() == null) {
    		result = "NOT-PAID";
    	} else if (line.getLineAttribute7() != null){
    		if (releasedStatus != null) {
    			if ("R".equals(releasedStatus) || "Y".equals(releasedStatus)) {
    				result = "RELEASED";
    			} else if ("B".equals(releasedStatus)) {
    				result = "BACKORDERED";
    			}
    		}
    	} else {
    		result = "RELEASED";
    	}
    	log.debug("getMCFLineStatus " +  result);
    	
    	return result;
    }
    
    
	/**
	 * Determines the value for order extension attributes ExtnDepositAmount and ExtnIsDepositAmountCollected.
	 * @TODO Validate this method for NumberFormatException
	 * @param attribute3
	 * @param attribute5
	 * @param field
	 * @return
	 */
	public static String getExtnDeposit(String attribute3, String attribute5, int field) {
		String result = "N";
		String value = ""+0;
		Float attr3amount = 0f;
		Float attr5amount = 0f;
		
		if (attribute3 != null) {
			attr3amount = Float.parseFloat(attribute3);
			value = "0";
		}
		
		if (attribute5 != null) {
			try {
				attr5amount = Float.parseFloat(attribute5);
			}
			catch(NumberFormatException nfe) {
				attr5amount = 0f; // validate this
			}
		}
		
		if ((attribute3 == null) || (attr3amount == 0)) {
			result = "N";
			value = "" + 0; 			
		} else if (attr3amount > 0 && attr5amount == 0) {
			result = "N";
			value = "" + attr3amount;			
		} else if (attr3amount > 0 && attr5amount.compareTo(attr3amount) == 0) {
			result = "Y";
			value = "" + attr3amount;			
		} else if (attr3amount > 0 && (attr5amount > attr3amount)) {
			result = "Y";
			value = "" + attr3amount;			
		}		

		return (field == 1) ? result : value; // flag : value
	}
	
	/**
	 * Calculates the value for ExtnAmountCollected at header level
	 * 
	 * @param orderDef
	 * @return
	 */
	public static BigDecimal getHeaderChargeTotal(OpenSalesOrderDefinition orderDef) {
		BigDecimal headerChargeTotal = new BigDecimal("0");		
		List<HeaderCharge> orderHeaderChargeList = orderDef.getHeaderChargeList();				
		if(orderHeaderChargeList!=null && orderHeaderChargeList.size()>0) {
			Iterator<HeaderCharge> iter=orderHeaderChargeList.iterator();			
			while(iter.hasNext()) {
				HeaderCharge charge=iter.next();
				headerChargeTotal = headerChargeTotal.add(charge.getChargeAmount());    			
			}
		}
		return headerChargeTotal;
	}

	/**
	 * Calculates the value for ExtnAmountCollected at line level
	 * @TODO - Total is not adding properly, fix this
	 * @param line
	 * @return
	 */
	public static Float getChargeTotal(OrderLine line) {
		List<LineCharge> lineChargesList = line.getLineChargeList();
		List<LineTax> lineTaxesList = line.getLineTaxList();
//		BigDecimal totalCharges = new BigDecimal("0");
		Float totalCharges = new Float("0.00");
		
		// add all line charges
		if(lineChargesList!=null && lineChargesList.size()>0) {
			Iterator<LineCharge> iter=lineChargesList.iterator();			
			while(iter.hasNext()) {
				LineCharge charge = iter.next();			
				totalCharges = totalCharges + Float.valueOf(charge.getChargePerUnit().toString());
			}
		}

		// add all taxes
		if(lineTaxesList!=null && lineTaxesList.size()>0) {
			Iterator<LineTax> iter=lineTaxesList.iterator();			
			while(iter.hasNext()) {
				LineTax tax = iter.next();				
				totalCharges = totalCharges + Float.valueOf(tax.getTax().toString());
			}
		}
		
		return totalCharges;
	}
	
	/**
	 * Get the document type for open and return orders
	 * 
	 * @param line
	 * @return
	 */
	public String getDocumentType(COFIOrderLine line) {
		int lineTypeId = line.getLineTypeId().intValue();
		String result = "0001";
		if (lineTypeId == 1006 || lineTypeId == 1007 || lineTypeId == 1005) {
			result = "0003";
		}
		return result;
	}
}